package com.douqu.game.core.entity.world;

import com.bean.core.buffer.ByteBuffer;
import com.douqu.game.core.config.StableDataConfig;
import com.douqu.game.core.config.common.GoodsData;
import com.douqu.game.core.config.major.MajorConfig;
import com.douqu.game.core.e.E_StableDataType;
import com.douqu.game.core.factory.DataFactory;
import com.douqu.game.core.i.ICalculateRandomField;
import com.douqu.game.core.protobuf.SGCommonProto;
import com.douqu.game.core.util.CoreUtils;
import com.douqu.game.core.util.LogUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @Author: zhenfei
 * @Description: 世界采集的个人信息
 * @Date: 2018-02-06 10:54
 */
public class WorldCollectBean {
    public static int MAX_GRAP_TIMES;
    public static double GRAP_PERCENT;
    /**
     * 参数，不参与数据存储
     **/
    public String param;
    private String objectIndex;
    private long endTime;
    private int collectId;
    private int productNum;
    /**
     * 被抢夺次数
     **/
    private int beGrabTimes;
    /**
     * 机器人
     **/
    private boolean isRobot;
    /**
     * 采集类型
     **/
    private int collectType = SGCommonProto.E_MAJOR_COLLECT_TYPE.MAJOR_COLLECT_TYPE_NORMAL.getNumber();
    /**
     * 采集的物品数量
     **/
    private List<GoodsData> goodsDatas = new CopyOnWriteArrayList<>();


    public WorldCollectBean()
    {
        StableDataConfig config = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY, E_StableDataType.MAX_GRAP_TIMES.getCode());
        if(config != null) MAX_GRAP_TIMES = config.intValue;
        config = DataFactory.getInstance().getGameObject(DataFactory.STABLE_DATA_KEY, E_StableDataType.GRAP_PERCENT.getCode());
        if(config != null) GRAP_PERCENT = config.intValue;
    }


    public WorldCollectBean(String objectIndex, List<GoodsData> list)
    {
        this();

        this.objectIndex = objectIndex;
        this.goodsDatas.addAll(list);
    }

    public WorldCollectBean(String objectIndex, long endTime, int collectType, int collectId, boolean isRobot, int productNum, MajorConfig majorConfig) {

        this();

        this.objectIndex = objectIndex;
        this.endTime = endTime;
        this.collectType = collectType;
        this.collectId = collectId;
        this.isRobot = isRobot;
        this.productNum = productNum;
        radnomGoods(majorConfig);
    }

    private void radnomGoods(MajorConfig majorConfig) {
        for (int i = 0; i < productNum; i++) {
            addCollectGoods(CoreUtils.getRandomObject(majorConfig.collectOutput, 0, new ICalculateRandomField<GoodsData>() {
                @Override
                public int getFieldValue(GoodsData goodsData) {
                    return goodsData.value;
                }
            }));
        }
    }

    private void addCollectGoods(GoodsData data) {
        int index = 0;
        index = goodsDatas.indexOf(data);
        if (index < 0) { //不存在
            goodsDatas.add(new GoodsData(data.type, data.id, 1));
        } else {
            goodsDatas.get(index).value += 1;
        }
    }

    public boolean isTimeIn() {
        return DataFactory.currentTime < endTime;
    }

    public void writeTo(ByteBuffer buffer) {
        buffer.writeUTF(objectIndex);
        buffer.writeLong(endTime);
        buffer.writeInt(productNum);
        buffer.writeShort(beGrabTimes);
        buffer.writeByte(collectType);
        buffer.writeBoolean(isRobot);
        buffer.writeShort(goodsDatas.size());
        for (GoodsData data : goodsDatas) {
            buffer.writeInt(data.type);
            buffer.writeInt(data.id);
            buffer.writeInt(data.value);
        }
        buffer.writeBoolean(false);
        //++++++++++++++++++++++++++++++++++
        buffer.writeInt(collectId);
    }

    public void loadFrom(ByteBuffer buffer) {
        objectIndex = buffer.readUTF();
        endTime = buffer.readLong();
        productNum = buffer.readInt();
        beGrabTimes = buffer.readShort();
        collectType = buffer.readByte();
        isRobot = buffer.readBoolean();
        int size = buffer.readShort();
        for (int i = 0; i < size; i++) {
            GoodsData data = new GoodsData(buffer.readInt(), buffer.readInt(), buffer.readInt());
            if (!data.checkGoods()) {
                LogUtils.error("读取物品错误：" + data.toString());
            }
            getGoodsDatas().add(data);
        }
        buffer.readBoolean();

        collectId = buffer.readInt();
    }

    public String getObjectIndex() {
        return objectIndex;
    }

    public void setObjectIndex(String objectIndex) {
        this.objectIndex = objectIndex;
    }

    public List<GoodsData> getGoodsDatas() {
        return goodsDatas;
    }

    /**
     * 结算自己被抢夺之后的材料
     *
     * @return
     */
    public GoodsData[] getAfterGrabGoods() {
        /*GoodsData[] datas = new GoodsData[goodsDatas.size()];
        for (int i = 0; i < goodsDatas.size(); i++) {
            GoodsData goodsData = goodsDatas.get(i);
            datas[i] = new GoodsData(goodsData.type, goodsData.id, (int) (goodsData.value * (100 - beGrabTimes * GRAP_PERCENT) / 100));
        }
        return datas;*/
        int overNum = (int) (productNum * (100 - beGrabTimes * GRAP_PERCENT) / 100);
        List<GoodsData> resultList = getGrabGoods(overNum);
        GoodsData[] datas = new GoodsData[overNum];
        resultList.toArray(datas);
        return datas;
    }

    public List<GoodsData> getGrabGoods() {
        return getGrabGoods((int) (productNum * GRAP_PERCENT / 100));
    }

    /**
     * 抢夺材料计算
     *
     * @return
     */
    public List<GoodsData> getGrabGoods(int grapNum) {
        if (grapNum < 1) {
            return null;
        }

        // 将数量分解
        List<GoodsData> tempList = new ArrayList<>();
        for (int i = 0; i < goodsDatas.size(); i++) {
            GoodsData goodsData = goodsDatas.get(i);
            for (int j = 0; j < goodsData.value; j++) {
                tempList.add(new GoodsData(goodsData.type, goodsData.id, 1));
            }
        }
        // 随机打乱
        Collections.shuffle(tempList);
        tempList = tempList.subList(0, grapNum);

        List<GoodsData> resultList = new ArrayList<>();
        for (GoodsData goodsData : tempList) {
            boolean same = false;
            for (GoodsData g : resultList) {
                if (g.id == goodsData.id) {
                    g.value += 1;
                    same = true;
                    break;
                }
            }
            if (!same) {
                resultList.add(new GoodsData(goodsData.type, goodsData.id, 1));
            }
        }
        return resultList;
    }

    public boolean addBeGrabTimes() {
        if (!isRobot) {
            if(beGrabTimes >= MAX_GRAP_TIMES){
                return false;
            }
            beGrabTimes++;
        }
        return true;
    }

    public boolean isBeGrabTimesEnough() {
        return beGrabTimes < MAX_GRAP_TIMES;
    }

    public boolean isRobot() {
        return isRobot;
    }

    public int getBeGrabTimes() {
        return beGrabTimes;
    }

    public int getCollectType() {
        return this.collectType;
    }

    public long getEndTime() {
        return endTime;
    }

    public int getCollectId() {
        return collectId;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof WorldCollectBean)) return false;

        WorldCollectBean that = (WorldCollectBean) o;

        if (!objectIndex.equals(that.objectIndex)) return false;

        return true;
    }

    @Override
    public int hashCode() {
        return objectIndex.hashCode();
    }

}
